package com.atguigu.gulimall.product.exception;

import com.atguigu.common.exception.BizCodeEnum;
import com.atguigu.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 全局统一异常处理，basePackages 表示，处理哪个包下面的异常
 * @RestControllerAdvice 这个注解的作用就是  @Responsebody + @ControllerAdvice
 */
@RestControllerAdvice(basePackages ="com.atguigu.gulimall.product.controller" )
@Slf4j
public class GulimallExceptionControllerAdvice {

    /**
     * 全局异常之 字段校验处理
     * 该异常是当我们javaBean中给字段加了验证时，比如加了@Notnull @NotBlank，等等，如果校验不通过，那么SpringMVC就会抛出该异常MethodArgumentNotValidException
     * 然后由@ControllerAdvice这个类来捕获，
     * @param e
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleValidException(MethodArgumentNotValidException e){
        Map<String,String> map = new HashMap<>();
        // 获取校验结果
        BindingResult bindingResult = e.getBindingResult();
        // 拿到校验不通过的字段
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        // 遍历每个字段，并获取该字段校验结果内容
        fieldErrors.forEach(item->{
            String msg = item.getDefaultMessage();
            String fieldName = item.getField();
            map.put(fieldName,msg);
        });
        return R.error(BizCodeEnum.VALID_EXCEPTION.getCode(),BizCodeEnum.VALID_EXCEPTION.getMs()).put("data",map);
    }

    /**
     * 当抛出其他异常没有被捕获时，那么就会被Exception来捕获
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public R handleException(Exception e){
        return R.error(400,"系统未知异常");
    }
}
